﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Styx;
using Styx.Common;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

namespace LevelingHelper
{
    class InventoryHandler
    {

        public static bool InventoryCheck = false;
        private static readonly Dictionary<uint, string> ItemUseOnOne = new Dictionary<uint, string>();
        private static readonly Dictionary<uint, string> ItemUseOnThree = new Dictionary<uint, string>();
        private static readonly Dictionary<uint, string> ItemUseOnFive = new Dictionary<uint, string>();
        private static readonly Dictionary<uint, string> ItemUseOnTen = new Dictionary<uint, string>();
        private static readonly Dictionary<uint, string> ItemRequiresSleep = new Dictionary<uint, string>();
        private static readonly Dictionary<uint, string> DestroyItems = new Dictionary<uint, string>();
        private static readonly Dictionary<uint, uint> SpecificQuestsItems = new Dictionary<uint, uint>();

        public static void CheckInventory()
        {
            if (!InventoryCheck) return;

            Main.Log("Checking inventory \\o/ !");

            // Loot Event has Finished
            List<WoWItem> myBagItems = ObjectManager.GetObjectsOfTypeFast<WoWItem>().Where(items => items.BagSlot != -1).ToList();
            myBagItems.ForEach(CheckItem);
            
            InventoryCheck = false;
            StyxWoW.SleepForLagDuration();
        }

        private static void CheckItem(WoWItem myItem)
        {
            if (myItem == null || StyxWoW.Me.FreeNormalBagSlots < 1) return;

            // check if item exists and is in bag and we have space
            if (ItemUseOnOne.ContainsKey(myItem.Entry))
            {
                // stacks of 1
                if (myItem.StackCount >= 1)
                    UseItem(myItem);
            }
            else if (ItemUseOnThree.ContainsKey(myItem.Entry))
            {
                // stacks of 3
                if (myItem.StackCount >= 3)
                    UseItem(myItem);
            }
            else if (ItemUseOnFive.ContainsKey(myItem.Entry))
            {
                // stacks of 5
                if (myItem.StackCount >= 5)
                    UseItem(myItem);
            }
            else if (ItemUseOnTen.ContainsKey(myItem.Entry))
            {
                // stacks of 10
                if (myItem.StackCount >= 10)
                    UseItem(myItem);
            }
            else if (DestroyItems.ContainsKey(myItem.Entry))
                DestroyItem(myItem);

            else if (SpecificQuestsItems.ContainsKey(myItem.Entry))
                IsItemLinkedToQuest(myItem, SpecificQuestsItems[myItem.Entry]);
        }

        public static void UseItem(WoWItem item)
        {
            Main.Log(string.Format("Using {0} we have {1}", item.Name, item.StackCount));

            // some (soulbound) items require an additional sleep to prevent a loot issue
            if (ItemRequiresSleep.ContainsKey(item.Entry)) { StyxWoW.SleepForLagDuration(); }

            Lua.DoString("UseItemByName(\"" + item.Name + "\")");
            StyxWoW.SleepForLagDuration();
        }

        public static void DestroyItem(WoWItem item)
        {
            Main.Log(string.Format("Destroying {0} we have {1}", item.Name, item.StackCount));
            item.PickUp();
            Lua.DoString("DeleteCursorItem()");
            StyxWoW.SleepForLagDuration();
        }

        public static void IsItemLinkedToQuest(WoWItem myItem, uint myQuestID)
        {
            if (StyxWoW.Me.QuestLog.GetCompletedQuests().Contains(myQuestID))
            {
                Main.Log(string.Format("We found an item linked to a quest, you've completed this quest so we can destroy it ! Destroying {0} we have {1}", myItem.Name, myItem.StackCount));
                DestroyItem(myItem);
            }
        }

        public static void LoadItemLists()
        {
            if (Main.GetItemListsPath == "") return;

            string[] filePaths = Directory.GetFiles(Main.GetItemListsPath, "*.itm");
            var fileType = ItemType.NULL;

            foreach (var file in filePaths)
            {

                IDictionary myDic = null;
                var mySplit = File.ReadAllLines(file);

                if (file.Contains("[QUESTS]"))
                    fileType = ItemType.Quests;

                if (file.Contains("[STACK1]"))
                    fileType = ItemType.Stack1;

                if (file.Contains("[STACK3]"))
                    fileType = ItemType.Stack3;
     
                if (file.Contains("[STACK5]"))
                    fileType = ItemType.Stack5;
    
                if (file.Contains("[STACK10]"))
                    fileType = ItemType.Stack10;

                if (file.Contains("[DESTROY]"))
                    fileType = ItemType.Destroy;

                if (file.Contains("[REQUIRESLEEP]"))
                    fileType = ItemType.Requiresleep;

                switch (fileType)
                {
                    case ItemType.Quests:
                        myDic = SpecificQuestsItems;
                        break;
                    case ItemType.Stack1:
                        myDic = ItemUseOnOne;
                        break;
                    case ItemType.Stack3:
                        myDic = ItemUseOnThree;
                        break;
                    case ItemType.Stack5:
                        myDic = ItemUseOnFive;
                        break;
                    case ItemType.Stack10:
                        myDic = ItemUseOnTen;
                        break;
                    case ItemType.Destroy:
                        myDic = DestroyItems;
                        break;
                    case ItemType.Requiresleep:
                        myDic = ItemRequiresSleep;
                        break;
                }

                if (myDic == null) continue;

                if(fileType != ItemType.Quests)
                    mySplit.ForEach(item => LoadDictionary(myDic, item));

                if(fileType == ItemType.Quests) 
                    mySplit.ForEach(item => LoadDictionary(myDic, item, true));
            }
        }

        public static void LoadDictionary(IDictionary selectedDic, string myItem)
        {
            uint myItemID = Convert.ToUInt32(myItem.Split(Convert.ToChar("|"))[0]);
            string myItemName = myItem.Split(Convert.ToChar("|"))[1];

            Main.Log(string.Format("ItemName : {0} / ItemID : {1}",myItemName,myItemID));

            selectedDic.Add(Convert.ToUInt32(myItemID), myItemName);
        }

        public static void LoadDictionary(IDictionary selectedDic, string myItem, bool isQuest)
        {
            uint myItemID = Convert.ToUInt32(myItem.Split(Convert.ToChar("|"))[0]);
            uint myQuestID = Convert.ToUInt32(myItem.Split(Convert.ToChar("|"))[2]);

           Main.Log(string.Format("(QuestItem) ItemID : {0} / QuestID : {1}", myItemID, myQuestID));

            selectedDic.Add(Convert.ToUInt32(myItemID), myQuestID);
        }

        public bool CanInteractWithInventory() { return !StyxWoW.Me.IsActuallyInCombat && !StyxWoW.Me.Mounted && !StyxWoW.Me.IsDead && !StyxWoW.Me.IsGhost; }

        private enum ItemType
        {
            NULL,
            Stack1,
            Stack3,
            Stack5,
            Stack10,
            Destroy,
            Requiresleep,
            Quests
        }

    }
}
